package storage

import (
	"fitness/go-admin/internal/model"
	"io"
	"mime/multipart"
	"os"
	"path/filepath"
	"strings"
)

// LocalStorage 本地文件系统存储
type LocalStorage struct {
	config *StorageConfig
}

// NewLocalStorage 创建本地存储实例
func NewLocalStorage(config *StorageConfig) *LocalStorage {
	// 确保目录存在
	os.MkdirAll(config.UploadPath, 0755)
	os.MkdirAll(filepath.Join(config.UploadPath, "avatar"), 0755)
	os.MkdirAll(filepath.Join(config.UploadPath, "certificate"), 0755)
	os.MkdirAll(filepath.Join(config.UploadPath, "training"), 0755)
	os.MkdirAll(filepath.Join(config.UploadPath, "thumbnail"), 0755)

	return &LocalStorage{config: config}
}

// SaveFile 保存文件到本地
func (s *LocalStorage) SaveFile(file multipart.File, fileName string, fileType model.FileType) (string, []byte, error) {
	// 构建文件路径
	fileDir := filepath.Join(s.config.UploadPath, string(fileType))
	filePath := filepath.Join(fileDir, fileName)

	// 保存文件
	out, err := os.Create(filePath)
	if err != nil {
		return "", nil, err
	}
	defer out.Close()

	if _, err := io.Copy(out, file); err != nil {
		return "", nil, err
	}

	// 生成URL
	fileURL := strings.Replace(filePath, s.config.UploadPath, s.config.BaseURL, 1)
	fileURL = strings.ReplaceAll(fileURL, "\\", "/")

	return fileURL, nil, nil // 本地存储不返回字节数组
}

// SaveThumbnail 保存缩略图
func (s *LocalStorage) SaveThumbnail(data []byte, fileName string) (string, []byte, error) {
	thumbnailDir := filepath.Join(s.config.UploadPath, "thumbnail")
	thumbnailPath := filepath.Join(thumbnailDir, "thumb_"+fileName)

	if err := os.WriteFile(thumbnailPath, data, 0644); err != nil {
		return "", nil, err
	}

	thumbnailURL := strings.Replace(thumbnailPath, s.config.UploadPath, s.config.BaseURL, 1)
	thumbnailURL = strings.ReplaceAll(thumbnailURL, "\\", "/")

	return thumbnailURL, nil, nil
}

// GetFile 获取文件内容
func (s *LocalStorage) GetFile(fileURL string) ([]byte, error) {
	filePath := strings.Replace(fileURL, s.config.BaseURL, s.config.UploadPath, 1)
	return os.ReadFile(filePath)
}

// DeleteFile 删除文件
func (s *LocalStorage) DeleteFile(fileURL string) error {
	filePath := strings.Replace(fileURL, s.config.BaseURL, s.config.UploadPath, 1)
	return os.Remove(filePath)
}

// GetStorageType 获取存储类型
func (s *LocalStorage) GetStorageType() model.StorageType {
	return model.StorageTypeLocal
}
